package com.example.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.demo.model.EsPmWorkCard;
import com.example.demo.service.PmWorkCardService;
import com.example.demo.vo.EsPmWorkCardVO;
import com.example.demo.vo.WorkCardReqVO;
import com.example.demo.vo.WorkHistroyRespVO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class PmWorkCardServiceImpl implements PmWorkCardService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @Value("${es.indexname.work}")
    private String wordIndexName;

    @SneakyThrows
    @Override
    public WorkHistroyRespVO getWorkCardHistoryList(WorkCardReqVO workCardDTO) {

        int currentPage = workCardDTO.getCurrentPage();
        int pageSize = workCardDTO.getPageSize();

        // 1. 构建查询条件
        SearchSourceBuilder sourceBuilder = buildSearchSourceBuilder(workCardDTO);

        // 2. 设置分页参数
        sourceBuilder.size(pageSize);

        // 3. 设置排序
        sourceBuilder.sort("completedDate", SortOrder.DESC);
        sourceBuilder.sort("id", SortOrder.DESC); // 确保排序唯一性

        // 4. 如果有searchAfter
        if (currentPage * pageSize <= 10000 && ObjectUtils.isEmpty(workCardDTO.getSearchAfter())) {
            sourceBuilder.from((currentPage - 1) * pageSize);
            SearchRequest searchRequest = new SearchRequest(wordIndexName);
            searchRequest.source(sourceBuilder);

            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            return convertToPage(response, workCardDTO);
        }
        // 5. 如果是后续分页，使用search_after
        else {
            // 这里需要从前端获取上一页最后一条记录的sort值
            Object[] searchAfter = workCardDTO.getSearchAfter();
            if (searchAfter != null) {
                sourceBuilder.searchAfter(searchAfter);
            }

            SearchRequest searchRequest = new SearchRequest(wordIndexName);
            searchRequest.source(sourceBuilder);

            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            return convertToPage(response, workCardDTO);
        }
    }

    private SearchSourceBuilder buildSearchSourceBuilder(WorkCardReqVO reqVO) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 基本条件
        boolQuery.filter(QueryBuilders.termQuery("workCardStatus", "4"));

        // 船舶ID条件
        if (reqVO.getVesselId() != null) {
            boolQuery.filter(QueryBuilders.termQuery("vesselId", reqVO.getVesselId()));
        } else if (reqVO.getVesselIds() != null && !reqVO.getVesselIds().isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("vesselId", reqVO.getVesselIds()));
        }

        if (reqVO.getVesselName() != null && !reqVO.getVesselName().isEmpty()) {
            BoolQueryBuilder vesselNameQuery = QueryBuilders.boolQuery()
                    .should(QueryBuilders.wildcardQuery("vesselNameCn", "*" + reqVO.getVesselName() + "*"))
                    .should(QueryBuilders.wildcardQuery("vesselNameEn", "*" + reqVO.getVesselName() + "*"));
            boolQuery.filter(vesselNameQuery);;
        }

        // 设备工作ID条件
        if (reqVO.getDevJobIds() != null && !reqVO.getDevJobIds().isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("devJobId", reqVO.getDevJobIds()));
        }

        // 设备编码/名称条件
        if (StringUtils.isNotBlank(reqVO.getDevName())) {
            BoolQueryBuilder devNameQuery = QueryBuilders.boolQuery()
                    .should(QueryBuilders.wildcardQuery("devNameCn", "*" + reqVO.getDevName() + "*"))
                    .should(QueryBuilders.wildcardQuery("devNameEn", "*" + reqVO.getDevName() + "*"))
                    .should(QueryBuilders.wildcardQuery("devCode", "*" + reqVO.getDevName() + "*"));
            boolQuery.filter(devNameQuery);
        }

        // 工作标题/名称条件
        if (StringUtils.isNotBlank(reqVO.getWorkName())) {
            BoolQueryBuilder jobNameQuery = QueryBuilders.boolQuery()
                    .should(QueryBuilders.wildcardQuery("jobName", "*" + reqVO.getWorkName() + "*"))
                    .should(QueryBuilders.wildcardQuery("jobContent", "*" + reqVO.getWorkName() + "*"));
            boolQuery.filter(jobNameQuery);
        }

        // 工单编号条件
        if (StringUtils.isNotBlank(reqVO.getWorkOrderNo())) {
            boolQuery.filter(QueryBuilders.wildcardQuery("workOrderNo", "*" + reqVO.getWorkOrderNo() + "*"));
        }

        // 日期范围条件
        if (reqVO.getCompletedStartTime() != null && reqVO.getCompletedEndTime() != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("completedDate")
                    .gte(reqVO.getCompletedStartTime().getTime())
                    .lte(reqVO.getCompletedEndTime().getTime()));
        }

        // 其他条件...

        sourceBuilder.query(boolQuery);
        return sourceBuilder;
    }

    private WorkHistroyRespVO convertToPage(SearchResponse response, WorkCardReqVO reqVO) {
        List<EsPmWorkCardVO> content = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            EsPmWorkCardVO card = JSON.parseObject(hit.getSourceAsString(), EsPmWorkCardVO.class);
            content.add(card);
        }

        // 获取总记录数
        long totalHits = response.getHits().getTotalHits();


        Object[] searchAfter = null;

        // 获取最后一个sort值，用于下一页
        if (!content.isEmpty()) {
            SearchHit lastHit = response.getHits().getHits()[response.getHits().getHits().length - 1];
            searchAfter = lastHit.getSortValues();
        }

        return new WorkHistroyRespVO(content, totalHits, searchAfter,null);
    }
}
